package com.room.search.service;

import com.room.search.core.page.TableDataInfo;
import com.room.search.domain.RoomCommunity;
import com.room.search.domain.RoomGoods;
import com.room.search.domain.RoomSearchCommunity;
import com.room.search.domain.enumeration.BkRoomTypeEnum;
import com.room.search.repository.RoomCommunityRepository;
import com.room.search.repository.RoomSecondCityListRepository;
import com.room.search.repository.search.RoomSearchCommunitySearchRepository;
import com.room.search.response.RoomResult;
import com.room.search.service.dto.CityAndDistrictDTO;
import com.room.search.service.dto.GetAllByProvinceAndCityDTO;
import com.room.search.service.dto.RoomCommunityDTO;
import com.room.search.service.dto.community.GetCommunityListDTO;
import com.room.search.service.mapper.RoomCommunityMapper;
import com.room.search.util.PageUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * Service Implementation for managing {@link RoomCommunity}.
 */
@Service
@Transactional
public class RoomCommunityService {

    private final Logger log = LoggerFactory.getLogger(RoomCommunityService.class);

    private final RoomCommunityRepository roomCommunityRepository;
    private final RoomCommunityMapper roomCommunityMapper;
    private final RoomSecondCityListRepository secondCityListRepository;
    private final RoomSearchCommunitySearchRepository communitySearchRepository;

    public RoomCommunityService(RoomCommunityRepository roomCommunityRepository,
                                RoomCommunityMapper roomCommunityMapper,
                                RoomSecondCityListRepository secondCityListRepository,
                                RoomSearchCommunitySearchRepository communitySearchRepository) {
        this.roomCommunityRepository = roomCommunityRepository;
        this.roomCommunityMapper = roomCommunityMapper;
        this.secondCityListRepository = secondCityListRepository;
        this.communitySearchRepository = communitySearchRepository;
    }

    /**
     * Save a roomCommunity.
     *
     * @return the persisted entity.
     */
    @Transactional
    public RoomResult save(RoomCommunityDTO dto) {

        //市
        String address = dto.getAddress();
        //区、县

        return roomCommunityRepository.findByName(dto.getName())
            .map(community -> {
                log.info("添加小区：{}", community);
                if (address.equals(community.getAddress())) {
                    return RoomResult.error("添加小区失败");
                }
                community = roomCommunityMapper.toEntity(dto);
                return saveCommunity(community);
            }).orElseGet(
                () -> {
                    RoomCommunity community = roomCommunityMapper.toEntity(dto);
                    return saveCommunity(community);
                }
            );
    }

    /**
     * 创建小区
     */
    private RoomResult saveCommunity(RoomCommunity community) {
        RoomCommunity save = roomCommunityRepository.save(community);

        RoomSearchCommunity communitySearch = new RoomSearchCommunity().communityId(save.getId())
            .average(Integer.parseInt(save.getAverage()));
        communitySearchRepository.save(communitySearch);
        return RoomResult.success("创建小区成功");
    }

    /**
     * Partially update a roomCommunity.
     *
     * @param roomCommunityDTO the entity to update partially.
     * @return the persisted entity.
     */
    public Optional<RoomCommunityDTO> partialUpdate(RoomCommunityDTO roomCommunityDTO) {
        log.debug("Request to partially update RoomCommunity : {}", roomCommunityDTO);

        return roomCommunityRepository
            .findById(roomCommunityDTO.getId())
            .map(existingRoomCommunity -> {
                roomCommunityMapper.partialUpdate(existingRoomCommunity, roomCommunityDTO);

                return existingRoomCommunity;
            })
            .map(roomCommunityRepository::save)
            .map(roomCommunityMapper::toDto);
    }

    /**
     * Get all the roomCommunities.
     *
     * @return the list of entities.
     */
    @Transactional(readOnly = true)
    public List<RoomCommunityDTO> findAll() {
        log.debug("Request to get all RoomCommunities");
        return roomCommunityRepository.findAll().stream().map(roomCommunityMapper::toDto).collect(Collectors.toCollection(LinkedList::new));
    }

    /**
     * Get one roomCommunity by id.
     *
     * @param id the id of the entity.
     * @return the entity.
     */
    @Transactional(readOnly = true)
    public Optional<RoomCommunityDTO> findOne(Long id) {
        log.debug("Request to get RoomCommunity : {}", id);
        return roomCommunityRepository.findById(id).map(roomCommunityMapper::toDto);
    }

    /**
     * Delete the roomCommunity by id.
     *
     * @param id the id of the entity.
     */
    public void delete(Long id) {
        log.debug("Request to delete RoomCommunity : {}", id);
        roomCommunityRepository.deleteById(id);
    }

    /**
     * 获取所有的小区
     * @param dto 搜索条件参数
     */
    public TableDataInfo getAllRoomCommunities(GetCommunityListDTO dto) {
        Pageable pageable = PageUtils.startPage();


        List<RoomCommunity> all = roomCommunityRepository.findAll((root, query, criteriaBuilder) -> {

            List<Predicate> predicates = new ArrayList<>();

            if (dto.getName() != null) {
                predicates.add(criteriaBuilder.like(root.get("name"), "%" + dto.getName() + "%"));
            }

            if (dto.getPropertyCompany() != null) {
                predicates.add(criteriaBuilder.like(root.get("propertyCompany"), "%" + dto.getPropertyCompany() + "%"));
            }

            if (dto.getDeveloper() != null) {
                predicates.add(criteriaBuilder.like(root.get("developer"), "%" + dto.getDeveloper() + "%"));
            }

            if (dto.getProvince() != null) {
                predicates.add(criteriaBuilder.equal(root.get("province"), dto.getProvince()));
            }

            if (dto.getCity() != null) {
                predicates.add(criteriaBuilder.like(root.get("city"), dto.getCity()));
            }

            return criteriaBuilder.and(predicates.toArray(new Predicate[0]));

        });
        List<RoomCommunityDTO> communityDTOS = roomCommunityMapper.toDto(all);
        Page<RoomCommunityDTO> page = PageUtils.listConvertToPage1(communityDTOS, pageable);
        return TableDataInfo.getTableDataInfo(page);
    }


    /**
     * 根据省市区获取所有的小区
     */
    public RoomResult getCommunityByProvinceAndCity(GetAllByProvinceAndCityDTO dto) {
        Pageable pageable = PageRequest.of(0, 4);
        List<RoomCommunity> communities = roomCommunityRepository.findAllByProvinceAndCity(dto.getProvince(), dto.getCity(), pageable);
        int size = communities.size() - 1;

        //如果不是首页
        if (!dto.isIndex()) {
            return RoomResult.success(roomCommunityMapper.toDto(communities));
        }

        //如果首页未到4个房源则填充空资源
        if (size != 3) {
            for (int i = 0; i < 3 - size; i++) {
                communities.add(new RoomCommunity());
            }
        }
        return RoomResult.success(roomCommunityMapper.toDto(communities));
    }


    public TableDataInfo getAllCommunityByDistrict(CityAndDistrictDTO dto) {
        Pageable pageable = PageRequest.of(0, 4);
        List<RoomCommunity> communities = roomCommunityRepository.findAllByCityAndDistrictLike(dto.getCity(), dto.getDistrict() + "%");
        Page<RoomCommunity> page = PageUtils.listConvertToPage1(communities, pageable);
        return TableDataInfo.getTableDataInfo(page);
    }
}
